package com.offroader.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期工具类
 * 
 * @author li.li
 *
 *         Sep 19, 2012
 */
public class DateUtils {
	// 时间
	public static long SECOND = 1000;// 秒
	public static long MINUTE = SECOND * 60;// 分
	public static long HOUR = MINUTE * 60;// 时
	public static long DAY = HOUR * 24;// 天

	//周几为一周的第一天，默认周一
	public static int FIRST_DAY_OF_WEEK = Calendar.MONDAY;

	public static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static final SimpleDateFormat format_hm = new SimpleDateFormat("HH:mm");
	public static final SimpleDateFormat format_str = new SimpleDateFormat("yyyymmddhhmmssms");
	public static final SimpleDateFormat format_day = new SimpleDateFormat("yyyy-MM-dd");
	public static final SimpleDateFormat format_minute = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	public static final SimpleDateFormat format_month_day = new SimpleDateFormat("MM月dd日");

	public static String format(Date date) {
		return format.format(date);
	}

	public static String formatDay(Date date) {
		return format_day.format(date);
	}

	public static String formatMinute(Date date) {
		return format_minute.format(date);
	}

	public static String formatHM(Date date) {
		return format_hm.format(date);
	}

	public static String format(long time) {
		if (String.valueOf(time).length() == 10)
			time = time * 1000;
		return format(new Date(time));
	}

	public static String formatDay(long time) {
		if (String.valueOf(time).length() == 10)
			time = time * 1000;
		return formatDay(new Date(time));
	}

	public static String formatMonthDay(Date date) {
		return format_month_day.format(date);
	}

	public static String formatMinute(long time) {
		if (String.valueOf(time).length() == 10)
			time = time * 1000;
		return formatMinute(new Date(time));
	}

	public static String getCurrentTime() {
		Date date = new Date();
		return format_str.format(date);
	}

	public static long getTime(String dateStr) {

		try {
			Date date = format.parse(dateStr);

			return date.getTime();
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return 0;
	}

	public static long getHmTime(String dateStr) {
		try {
			Date date = format_hm.parse(dateStr);

			return date.getTime();
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return 0;
	}

	public static String now() {
		return format.format(new Date());
	}

	/**
	 * 是否是同一天
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static boolean isSameDay(long data1, long data2) {
		try {
			Date date1 = new Date(data1);
			Date date2 = new Date(data2);

			return isSameDay(date1, date2);
		} catch (Throwable e) {
			e.printStackTrace();
		}

		return false;

	}

	/**
	 * 是否是同一天
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static boolean isSameDay(String dateStr1, String dateStr2) {
		try {
			Date date1 = format.parse(dateStr1);
			Date date2 = format.parse(dateStr2);

			return isSameDay(date1, date2);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return false;

	}

	/**
	 * 是否是同一天
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static boolean isSameDay(Date date1, Date date2) {
		if (date1 == null || date2 == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar cal1 = Calendar.getInstance();
			cal1.setTime(date1);
			Calendar cal2 = Calendar.getInstance();
			cal2.setTime(date2);
			return isSameDay(cal1, cal2);
		}
	}

	/**
	 * 是否是同一周
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static boolean isSameWeek(Date date1, Date date2) {
		if (date1 == null || date2 == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar cal1 = Calendar.getInstance();
			cal1.setTime(date1);
			Calendar cal2 = Calendar.getInstance();
			cal2.setTime(date2);
			return isSameWeek(cal1, cal2);
		}
	}

	/**
	 * time以内
	 * 
	 * @param dateStr
	 * @return
	 */
	public static boolean isInside(String dateStr, long time) {

		long last = DateUtils.getTime(dateStr);
		long now = System.currentTimeMillis();
		if ((now - last) < time)
			return true;

		return false;
	}

	/**
	 * 一小时以外
	 * 
	 * @param dateStr
	 * @return
	 */
	public static boolean isOutHour(String dateStr, long time) {
		long last = DateUtils.getTime(dateStr);
		long now = System.currentTimeMillis();
		if ((now - last) >= time)
			return true;

		return false;
	}

	public static boolean isSameDay(Calendar cal1, Calendar cal2) {
		if (cal1 == null || cal2 == null)
			throw new IllegalArgumentException("The date must not be null");
		else
			return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
					&& cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
	}

	public static boolean isSameWeek(Calendar cal1, Calendar cal2) {
		if (cal1 == null || cal2 == null)
			throw new IllegalArgumentException("The date must not be null");
		else
			return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
					&& cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR);
	}

	public static boolean after(Date date) {
		long time = date.getTime();
		long now = System.currentTimeMillis();
		if (now > time)
			return true;

		return false;
	}

	// 增加或减少天数
	public static Date addDay(Date date, int num) {
		Calendar startDT = Calendar.getInstance();
		startDT.setTime(date);
		startDT.add(Calendar.DAY_OF_MONTH, num);
		return startDT.getTime();
	}

	// 增加或减少分钟
	public static Date addMinite(Date date, int minites) {
		Calendar startDT = Calendar.getInstance();
		startDT.setTime(date);
		startDT.add(Calendar.MINUTE, minites);
		return startDT.getTime();
	}

	/**
	 * 得到当前时间戳
	 * 
	 * @return
	 */
	public static String getStrTimestamp() {

		return getStrTimestamp(10);

	}

	/**
	 * 得到当前时间戳
	 * 
	 * @return
	 */
	public static String getStrTimestamp(int maxLength) {
		String t = String.valueOf(System.currentTimeMillis());
		t = t.substring(0, Math.min(maxLength, t.length()));

		return t;

	}

	/**
	 * 得到当前时间戳
	 * 
	 * @return
	 */
	public static long getTimestamp() {

		return getTimestamp(10);

	}

	/**
	 * 得到当前时间戳
	 * 
	 * @return
	 */
	public static long getTimestamp(int maxLength) {
		String t = String.valueOf(System.currentTimeMillis());
		t = t.substring(0, Math.min(maxLength, t.length()));

		return Long.valueOf(t);

	}

	/**
	* 获取当前日期是星期几<br>
	* 
	* @param dt
	* @return 当前日期是星期几
	*/
	public static String getWeekOfDate(Date dt) {
		String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
		Calendar cal = Calendar.getInstance();
		cal.setTime(dt);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return weekDays[w];
	}

	/**
	* 获取当前日期是星期几<br>
	* 
	* @param dt
	* @return 当前日期是星期几
	*/
	public static String getWeekOfDate(Date dt, String[] weekDays) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(dt);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return weekDays[w];
	}

	/**
	 * 当前的第几周
	 * @param date
	 * @return
	 */
	public static int getWeekInYear(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
		cal.setTime(date);

		return cal.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 当前的第几周
	 * @param date
	 * @return
	 */
	public static int getWeekInMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
		cal.setTime(date);

		return cal.get(Calendar.WEEK_OF_MONTH);
	}

	/**
	 * 当前的第几月
	 * @param date
	 * @return
	 */
	public static int getMonthInYear(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.SUNDAY);
		cal.setTime(date);

		return cal.get(Calendar.MONTH) + 1;
	}

	/**
	 * 当前的第几天
	 * @param date
	 * @return
	 */
	public static int getDayInWeek(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
		cal.setTime(date);

		return cal.get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * 当前的第几天
	 * @param date
	 * @return
	 */
	public static int getDayInMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
		cal.setTime(date);

		return cal.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 当前哪年
	 * @param date
	 * @return
	 */
	public static int getYear(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
		cal.setTime(date);

		return cal.get(Calendar.YEAR);
	}

	public static int getHour(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
		cal.setTime(date);

		return cal.get(Calendar.HOUR_OF_DAY);
	}

	public static int getMinute(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
		cal.setTime(date);

		return cal.get(Calendar.MINUTE);
	}

	/**
	 * 根据某年的第几周得到当前周的日期 
	 * @param date
	 * @return
	 */
	public static List<Date> dateToWeek(int year, int week) {

		Calendar cal = Calendar.getInstance();

		//设置第一天为周日
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);

		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, week);
		Date date = cal.getTime();
		cal.setTime(date);

		List<Date> list = new ArrayList<Date>(7);

		//周日
		if (FIRST_DAY_OF_WEEK == Calendar.SUNDAY) {
			cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			list.add(cal.getTime());
		}

		//周一
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		list.add(cal.getTime());
		//周二
		cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
		list.add(cal.getTime());
		//周三
		cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
		list.add(cal.getTime());
		//周四
		cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
		list.add(cal.getTime());
		//周五
		cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
		list.add(cal.getTime());
		//周六
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
		list.add(cal.getTime());

		if (FIRST_DAY_OF_WEEK == Calendar.MONDAY) {
			cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			list.add(cal.getTime());
		}

		return list;
	}

	/**
	 * 根据某年某月的第几周得到当前周的日期
	 * @param date
	 * @return
	 */
	public static List<Date> dateToWeek(int year, int month, int week) {

		Calendar cal = Calendar.getInstance();

		//设置第一天为周日
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);

		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);
		cal.set(Calendar.WEEK_OF_MONTH, week);
		Date date = cal.getTime();
		cal.setTime(date);

		List<Date> list = new ArrayList<Date>(7);

		//周日
		if (FIRST_DAY_OF_WEEK == Calendar.SUNDAY) {
			cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			list.add(cal.getTime());
		}

		//周一
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		list.add(cal.getTime());
		//周二
		cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
		list.add(cal.getTime());
		//周三
		cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
		list.add(cal.getTime());
		//周四
		cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
		list.add(cal.getTime());
		//周五
		cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
		list.add(cal.getTime());
		//周六
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
		list.add(cal.getTime());

		if (FIRST_DAY_OF_WEEK == Calendar.MONDAY) {
			cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			list.add(cal.getTime());
		}

		return list;
	}

	/**
	 * 根据日期获得所在周的日期 
	 * @param date
	 * @return
	 */
	public static List<Date> dateToWeek(Date date) {

		Calendar cal = Calendar.getInstance();

		//设置第一天为周日
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);
		cal.setTime(date);

		List<Date> list = new ArrayList<Date>(7);

		//周日
		if (FIRST_DAY_OF_WEEK == Calendar.SUNDAY) {
			cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			list.add(cal.getTime());
		}

		//周一
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		list.add(cal.getTime());
		//周二
		cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
		list.add(cal.getTime());
		//周三
		cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
		list.add(cal.getTime());
		//周四
		cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
		list.add(cal.getTime());
		//周五
		cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
		list.add(cal.getTime());
		//周六
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
		list.add(cal.getTime());

		if (FIRST_DAY_OF_WEEK == Calendar.MONDAY) {
			cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			list.add(cal.getTime());
		}

		return list;
	}

	/**
	 * 根据日期获得所在月的日期 
	 * @param date
	 * @return
	 */
	public static List<Date> dateToMonth(Date date) {

		int year = getYear(date);
		int month = getMonthInYear(date);
		int dayCountOfMonth = getDayCountByMonth(year, month);

		Calendar cal = Calendar.getInstance();

		//设置第一天为周日
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);

		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);

		List<Date> list = new ArrayList<Date>();

		for (int i = 0; i < dayCountOfMonth; i++) {

			cal.set(Calendar.DAY_OF_MONTH, i + 1);

			list.add(cal.getTime());

		}

		return list;
	}

	/**
	 * 根据日期获得所在月的日期 
	 * @param date
	 * @return
	 */
	public static List<Date> dateToMonth(int year, int month) {

		int dayCountOfMonth = getDayCountByMonth(year, month);

		Calendar cal = Calendar.getInstance();

		//设置第一天为周日
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);

		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);

		List<Date> list = new ArrayList<Date>();

		for (int i = 0; i < dayCountOfMonth; i++) {

			cal.set(Calendar.DAY_OF_MONTH, i + 1);

			list.add(cal.getTime());

		}

		return list;
	}

	public static int getDayCountByYear(int year) {

		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);//设置第一天为周日
		cal.set(Calendar.YEAR, year); // 例如2015

		int count = cal.getActualMaximum(Calendar.DAY_OF_YEAR);

		return count;

	}

	public static int getDayCountByMonth(int year, int month) {

		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);//设置第一天为周日
		cal.set(Calendar.YEAR, year); // 例如2015
		cal.set(Calendar.MONTH, month - 1); //  0表示一月，1表示二月,例如：5表示6月

		int count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

		return count;

	}

	public static int getWeekCountByYear(int year) {

		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);//设置第一天为周日
		cal.set(Calendar.YEAR, year); // 例如2015

		int count = cal.getActualMaximum(Calendar.WEEK_OF_YEAR);

		return count;

	}

	public static int getWeekCountByMonth(int year, int month) {

		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(FIRST_DAY_OF_WEEK);//设置第一天为周日
		cal.set(Calendar.YEAR, year); // 例如：2015
		cal.set(Calendar.MONTH, month - 1); //  0表示一月，1表示二月,例如：5表示6月

		int count = cal.getActualMaximum(Calendar.WEEK_OF_MONTH);

		return count;

	}

	/**  
	* 计算两个日期之间相差的天数  
	* @param smdate 较小的时间 
	* @param bdate  较大的时间 
	* @return 相差天数 
	* @throws ParseException  
	*/
	public static int daysBetween(Date smdate, Date bdate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		smdate = sdf.parse(sdf.format(smdate));
		bdate = sdf.parse(sdf.format(bdate));
		Calendar cal = Calendar.getInstance();
		cal.setTime(smdate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(bdate);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}

}
